/********************************************************************************
 * Copyright (c)2016-2020, ShenZhen WanJiaAn Technology CO.,LTD.
 * All Rights Reserved.
 *
 * File Name     : System.c
 * Author        : joki.zhu
 * Date          : 2019-10-18
 *
 * Record        :
 * 1.Date        : 2019-10-18
 *   Author      : joki.zhu
 *   Modification: Created file
 ********************************************************************************/
#include "System.h"
#include <tzdst.h>
#include "hi_timestamp.h"
#include "chip_config.h"

#ifdef __HuaweiLite__
#include <liteos/sysinfo.h>
#endif /* __HuaweiLite__ */

#ifdef TELNET_ON
extern int telnet_cmd(UINT32 argc, UINT8 **argv);
extern int TelnetCmd(UINT32 argc, UINT8 **argv);
void SystemTelnetOn(void)
{
    UINT32 argc = 1;
    UINT8 *argv[] = {"on"};
#ifdef HI3516EV200_V5_0_2_0
    TelnetCmd(argc, argv);
#else
    telnet_cmd(argc, argv);
#endif
}

void SystemTelnetOff(void)
{
    UINT32 argc = 1;
    UINT8 *argv[] = {"off"};
    telnet_cmd(argc, argv);    
}
#endif /* TELNET_ON */

AV_VOID SystemReboot(char *reason)
{
    sync();
#ifdef __HuaweiLite__
    SocSubSetResetSwitch(0);
    if (SocSubCheckIsUpgrading()) {
        LOGW("soc sub is upgrading, can't reboot system\n");
        return ;
    }
    /* clear mcu wakeup event */
    SocSubSetClearWakeupEvent();
    
    LOGW("system reboot the reason: %s\n", reason);
    usleep(50 * 1000);
    void cmd_reset(void);
    cmd_reset();
#else
    reboot();    
#endif /* __HuaweiLite__ */
}

AV_VOID SystemReset(void)
{
    sync();
#ifdef __HuaweiLite__
    SocSubSetResetSwitch(0);
    usleep(50 * 1000);
    void cmd_reset(void);
    cmd_reset();
#endif /* __HuaweiLite__ */
}

void SystemSetUpdateFlag(void)
{
#ifdef __HuaweiLite__
    himm(PWR_USER_REG1, 0x1);
#endif /* __HuaweiLite__ */
}

int SystemSetTimeNtp(int serverNum, char **serverAddr)
{
    if (serverAddr == NULL) {
        LOGE("serverAddr is NULL\n");
        return -1;
    }
    
#ifdef __HuaweiLite__    
    LOGI("start!\n");
	int ret_server_num;
	struct timeval get_time;
	
	memset(&get_time, 0, sizeof(get_time));
	ret_server_num = lwip_sntp_start(serverNum, serverAddr, &get_time);
	if (ret_server_num < 0) {
			return -1;
	}
    if (ctime((time_t *)&get_time.tv_sec) != NULL) {
        LOGD("time server %s: %d\n", serverAddr[ret_server_num], ret_server_num);
	}
    
	LOGI("end!\n");
#endif /* __HuaweiLite__ */

	return 0;	
}

int SystemSetTimeZone(SYS_TIMEZONE_INFO_S stTimeZoneInfo)
{
#ifdef __HuaweiLite__
	#if 1
	int hour = 0;
	int min  = 0;
	int totalsec  = 0;
    char zonebuf[32] = "";

	totalsec = abs(stTimeZoneInfo.zoneSec);
    hour = totalsec / 3600;
	min  = (totalsec % 3600)/60;
	if(stTimeZoneInfo.zoneSec > 0){
    	snprintf(zonebuf, sizeof(zonebuf), "tzn+%02d:%02d:00", hour, min);
	}else{
		snprintf(zonebuf, sizeof(zonebuf), "tzn-%02d:%02d:00", hour, min);
	}
	LOGD("zonebuf=%s\n",zonebuf);
    settimezone(zonebuf);
	#else
	struct timezone tz;
	gettimeofday(NULL, &tz);
	tz.tz_minuteswest = stTimeZoneInfo.zoneSec/60;  
	settimeofday(NULL, &tz);
	#endif
#endif /* __HuaweiLite__ */

    return 0;
}

int SystemPrintBootTime(char *keyword)
{
#ifdef __HuaweiLite__
    //存在问题
    HI_PrintBootTime(keyword);
#endif /* __HuaweiLite__ */

    return 0;
}


int SystemGetCurrentTime(SYSTEM_TIME *pTime)
{
    time_t nowTime;
    struct tm stTime = {0,};
    
    time(&nowTime);
    localtime_r(&nowTime, &stTime);

    pTime->second   = stTime.tm_sec;
    pTime->minute   = stTime.tm_min;
    pTime->hour     = stTime.tm_hour;
    pTime->wday     = stTime.tm_wday;
    pTime->day      = stTime.tm_mday;
    pTime->month    = stTime.tm_mon + 1;
    pTime->year     = stTime.tm_year + 1900;

    return 0;
}

int SystemSetCurrentTime(SYSTEM_TIME *pTime)
{
    time_t t = 0L;
    struct tm stTime;
    
    memset(&stTime, 0, sizeof(struct tm));
    stTime.tm_year = pTime->year - 1900;
    stTime.tm_mon = pTime->month - 1;
    stTime.tm_mday = pTime->day;
    stTime.tm_hour = pTime->hour;
    stTime.tm_min = pTime->minute;
    stTime.tm_sec = pTime->second;

    LOGI("%04d-%02d-%02d %02d:%02d:%02d\n", (int)stTime.tm_year+1900, (int)stTime.tm_mon+1, (int)stTime.tm_mday,
                                                 (int)stTime.tm_hour, (int)stTime.tm_min, (int)stTime.tm_sec);

    t = mktime(&stTime);
    struct timeval stNowTime = {t, 0};
    settimeofday(&stNowTime, NULL);

    return 0;
}

// 零时区时间, 即不带时区的时间
int SystemGetCurrentTimeUtc(SYSTEM_TIME *pTime)
{
    time_t nowTime;
    struct tm tmTime = {0};

    nowTime = time(NULL);
    gmtime_r(&nowTime, &tmTime);

    pTime->second   = tmTime.tm_sec;
    pTime->minute   = tmTime.tm_min;
    pTime->hour     = tmTime.tm_hour;
    pTime->wday     = tmTime.tm_wday;
    pTime->day      = tmTime.tm_mday;
    pTime->month    = tmTime.tm_mon + 1;
    pTime->year     = tmTime.tm_year + 1900;
    
    return 0;
}

int SystemGetSysInfo(SYSTEM_INFO_S *pstSysInfo)
{
	if (pstSysInfo == NULL) {
		LOGE("param is invalid!\n");
		return -1;
	}
#ifdef __HuaweiLite__	
	unsigned int uwMemUsed = 0;
	unsigned int uwTotalMem = 0;
	unsigned int uwFreeMem = 0;
	
	uwMemUsed = LOS_MemTotalUsedGet(m_aucSysMem1);
	uwTotalMem = LOS_MemPoolSizeGet(m_aucSysMem1);
	uwFreeMem = uwTotalMem - uwMemUsed;

	pstSysInfo->totalMemSize = uwTotalMem;
	pstSysInfo->freeMemSize = uwFreeMem;
	printf("freeMemSize==========%u\n", pstSysInfo->freeMemSize);
#endif /* __HuaweiLite__ */
	
	return 0;
}

